home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / networking / amitcp / amislate1.0.lha / AmiSlate1.0 / SlateRexx / chess.rexx < prev    next >
Encoding:
OS/2 REXX Batch file  |  1995-03-13  |  28.7 KB  |  971 lines

  1. /* Chess for AmiSlate v1.0! */
  2.  
  3. /* Constants for use with AmiSlate's ARexx interface */
  4. AMode.DOT      =  0 
  5. AMode.PEN      =  1 
  6. AMode.LINE     =  2 
  7. AMode.CIRCLE   =  3 
  8. AMode.SQUARE   =  4 
  9. AMode.POLY     =  5 
  10. AMode.FLOOD    =  6 
  11. AMode.DTEXT    =  7 
  12.  
  13. AMessage.TIMEOUT     = 1    /* No events occurred in specified time period */
  14. AMessage.MESSAGE     = 2    /* Message recieved from remote Amiga */
  15. AMessage.MOUSEDOWN   = 4    /* Left mouse button press in drawing area */
  16. AMessage.MOUSEUP     = 8    /* Left mouse button release in drawing area */
  17. AMessage.RESIZE      = 16    /* Window was resized--time to redraw screen? */ 
  18. AMessage.QUIT        = 32    /* AmiSlate is shutting down */
  19. AMessage.CONNECT     = 64    /* Connection established */
  20. AMessage.DISCONNECT  = 128    /* Connection broken */
  21. AMessage.TOOLSELECT  = 256    /* Tool Selected */
  22. AMessage.COLORSELECT = 512    /* Palette Color selected */
  23. AMessage.KEYPRESS    = 1024    /* Key pressed */
  24.  
  25. ACTIVE  = 1
  26. PASSIVE = 0
  27.  
  28. /* Chess specific constants */
  29. HILITEPEN = 2
  30. SQUAREPEN1 = 3        /* It would probably be better to get these */
  31. SQUAREPEN2 = 4        /* dynamically, wouldn't it? */
  32. SIDE1PEN   = 2
  33. SIDE2PEN   = 1
  34.  
  35. piece.BLANK  = 0
  36. piece.PAWN   = 1
  37. piece.ROOK   = 2
  38. piece.KNIGHT = 4
  39. piece.BISHOP = 8
  40. piece.QUEEN  = 16
  41. piece.KING   = 32
  42.  
  43. /* Defaults */
  44. BInitialSquareSet = 0
  45.  
  46. /* Get our host's name--always given as first argument when run from Amislate */
  47. parse arg CommandPort ActiveString
  48.  
  49. /* Send all commands to this host */
  50. address (CommandPort) 
  51.  
  52. options results
  53.  
  54. /* Reserves pixels for a future toolbar -- currently, none */
  55. ToolBarHeight = 0
  56.  
  57. /* Check to see which tool is selected, whether we are connected */
  58. BFlood = 0
  59. GetStateAttrs stem stateattrs.
  60. if (stateattrs.mode >= 1) then BFlood = 1
  61.  
  62. /* Parse command line argument to see if we've been activated by 
  63.    a remote request or a local user */
  64. check = upper(left(ActiveString,3))
  65. if (upper(left(ActiveString,3)) ~= 'RE') then 
  66.     do
  67.         BActive = 1
  68.     end
  69.     else
  70.     do    
  71.         BActive = 0
  72.     end
  73.  
  74. /* See if we're connected */
  75. GetRemoteStateAttrs stem rstateattrs.
  76.  
  77. if (rstateattrs.mode > -1) then 
  78.     do
  79.         BConnectMode = 1
  80.     end
  81.     else
  82.     do
  83.         BConnectMode = 0
  84.     end
  85.     
  86. 'lock on'            /* keep user from drawing */
  87. 'lockpalette on'        /* match colors, if possible */
  88.  
  89. success = InitChessArray()
  90.  
  91. /* Initiator goes first */
  92. turn = ACTIVE
  93.  
  94. /* Handshaking for two-computer game */
  95. if (BConnectMode = 1) then 
  96. do
  97.     if (BActive == 1) then 
  98.     do
  99.         SetWindowTitle '"'||"Requesting game from remote user"||'"' 
  100.     RemoteRexxCommand '"'||"Would you like to play chess?"||'"' "slaterexx:chess.rexx"
  101.     
  102.         waitevent stem handshake. MESSAGE
  103.         if (handshake.message == 0) then 
  104.         do
  105.             SetWindowTitle '"'||"Chess Game Refused"||'"'
  106.             exit
  107.         end
  108.     success = DrawChessBoard()
  109.     SetRemoteWindowTitle '"'||"Their Turn (White)"||'"'
  110.     end
  111.     else
  112.     do
  113.         /* Examine window to get dimensions */
  114.     GetWindowAttrs stem winattrs.
  115.        BoardWidth = winattrs.width  - 58
  116.        BoardHeight= winattrs.height - 53 - ToolBarHeight
  117.     end
  118. end
  119. else 
  120. do
  121.     success = DrawChessBoard()
  122. end        
  123.  
  124. success = UpdateStatus()
  125. do while(1)
  126.     waitevent stem event. RESIZE MOUSEDOWN MOUSEUP TOOLSELECT MESSAGE DISCONNECT
  127.  
  128.     if (event.type == AMessage.DISCONNECT) then BConnectMode = 0
  129.     if (event.type == AMessage.QUIT) then exit
  130.     if (event.type == AMessage.RESIZE) then do
  131.         if ((BActive == 1)|(BConnectMode == 0)) then do
  132.            success = DrawChessBoard()
  133.         end
  134.         else do
  135.            /* Just examine window to get new dimensions */
  136.            GetWindowAttrs stem winattrs.
  137.            BoardWidth = winattrs.width  - 58
  138.            BoardHeight= winattrs.height - 53 - ToolBarHeight
  139.         end
  140.              success = UpdateStatus()
  141.     end
  142.         
  143.     if (event.type == AMessage.MESSAGE) then do
  144.         if (turn ~= BActive) then do
  145.             success = ParseMove(event.message)
  146.             if (success == 1) then do
  147.                 turn = BActive
  148.                 success = UpdateStatus()
  149.                 end
  150.             end
  151.         end
  152.         
  153.     if ((event.type = AMessage.TOOLSELECT)&(BActive == 1)) then do
  154.         BOldFlood = BFlood
  155.         if (event.code1 < 1) then BFlood = 0
  156.         if (event.code1 >= 1) then BFlood = 1
  157.         if ((event.code1 = 7)|(BFlood ~= BOldFlood)) then success = DrawChessBoard()
  158.         end
  159.  
  160.     if (((event.type = AMessage.MOUSEDOWN)|((event.type = AMessage.MOUSEUP)&(BInitialSquareSet = 1)))&((turn = BActive)|(BConnectMode = 0))) then do
  161.         xtemp = event.x
  162.         SelectChessSquareX = -1
  163.         say xtemp BoardWidth
  164.         do while (xtemp > 0)
  165.             xtemp = xtemp - trunc(BoardWidth / 8)
  166.             SelectChessSquareX = SelectChessSquareX + 1
  167.             end
  168.         ytemp = event.y
  169.         SelectChessSquareY = -1
  170.         do while (ytemp > ToolBarHeight)
  171.             ytemp = ytemp - trunc(BoardHeight / 8)
  172.             SelectChessSquareY = SelectChessSquareY + 1
  173.             end
  174.  
  175.         ThisSquare = ChessBoard.SelectChessSquareX.SelectChessSquareY        
  176.         if (((turn == ACTIVE)&(ThisSquare > 0))|((turn == PASSIVE)&(ThisSquare < 0))|(BInitialSquareSet == 1)) then do
  177.    
  178.                /* HiLite selected square */
  179.             success = SelectChessSquare(SelectChessSquareX, SelectChessSquareY, HiLitePen)
  180.     
  181.              if (BInitialSquareSet = 0) then do
  182.                 BInitialSquareSet = 1
  183.                 SelectedSquareX = SelectChessSquareX
  184.                 SelectedSquareY = SelectChessSquareY
  185.                 end
  186.             else do
  187.                 /* De-HiLite old square */
  188.                 sqc = SquareColor(SelectedSquareX, SelectedSquareY)
  189.                 success = SelectChessSquare(SelectedSquareX, SelectedSquareY, sqc)
  190.             
  191.                 /* De-HiLite this square--move done! */    
  192.                 sqc = SquareColor(SelectChessSquareX, SelectChessSquareY)
  193.                 success = SelectChessSquare(SelectChessSquareX,SelectChessSquareY, sqc)
  194.     
  195.                 BInitialSquareSet = 0
  196.     
  197.                 if (MovePiece(SelectedSquareX, SelectedSquareY, SelectChessSquareX, SelectChessSquareY) == 1) then do
  198.                     szSendString = "@" || selectedSquareX || SelectedSquareY || SelectChessSquareX || SelectChessSquareY || "@"
  199.                     sendmessage szSendString
  200.                     if (turn == 1) then do
  201.                         turn = 0
  202.                         end
  203.                     else do
  204.                         turn = 1
  205.                         end
  206.                     success = UpdateStatus()
  207.                     end
  208.                 else do
  209.                     SetWindowTitle '"'||"Illegal Move!"||'"'
  210.                     end
  211.                 end
  212.             end
  213.         end
  214.     end
  215. exit
  216.  
  217.  
  218.  
  219. /* --------------------------------------------------------------- */
  220. /* procedure MovePiece                           */
  221. /* --------------------------------------------------------------- */
  222. MovePiece: procedure expose ChessBoard. piece. PiecePosX. PiecePosY. BoardWidth  BoardHeight ToolBarHeight SQUAREPEN1 SQUAREPEN2 SIDE1PEN SIDE2PEN  HILITEPEN BFlood
  223.     parse arg OldX, OldY, X, Y
  224.     
  225.     if (CheckMove(OldX, OldY, X, Y, 1) == 0) then return 0    
  226.     
  227.     if (UpdatePiecePos(OldX, OldY, X, Y) == 0) then do
  228.         EasyRequest Chess_Error "555:UPP_failed" Okay
  229.         return 0
  230.         end    
  231.     
  232.     /* Was there a death here?  If so, remove dying piece */
  233.     if (ChessBoard.X.Y ~= Piece.BLANK) then do
  234.         VictimPiece = GetPiecePos(X, Y)
  235.         if (VictimPiece > 0) then do
  236.             PiecePosX.1.VictimPiece = 9999
  237.             PiecePosY.1.VictimPiece = 9999
  238.             end
  239.         else do
  240.             VictimPiece = abs(VictimPiece)
  241.             PiecePosX.2.VictimPiece = 9999
  242.             PiecePosY.2.VictimPiece = 9999
  243.             end
  244.         end
  245.         
  246.     ChessBoard.X.Y = ChessBoard.OldX.OldY              /* Then put the piece in the new spot! */
  247.     ChessBoard.OldX.OldY = Piece.BLANK
  248.     
  249.     success=DrawPiece(OldX, OldY, ChessBoard.OldX.OldY, BFlood)
  250.     success=DrawPiece(X, Y, ChessBoard.X.Y, BFlood)
  251.                     
  252.     return 1
  253.  
  254.  
  255. /* --------------------------------------------------------------- */
  256. /* procedure MoveCreatesCheck                           */
  257. /*                                   */
  258. /* This procedure will determine if the move (OldX,OldY)->(X,Y)    */
  259. /* will get the piece at CheckX, CheckY into danger (i.e. check    */
  260. /* for a king, etc. ) without affecting the board              */
  261. /* --------------------------------------------------------------- */
  262. MoveCreatesCheck: procedure expose ChessBoard. piece. PiecePosX. PiecePosY. 
  263.     parse arg OldX, OldY, X, Y, CheckX, CheckY
  264.     
  265.     if (ChessBoard.OldX.OldY == Piece.BLANK) then do
  266.         EasyRequest Chess_Error "MoveCreatesCheck:_Bad_Attacker!" Okay
  267.         return 1
  268.         end
  269.     
  270.     AttackerPiece = ChessBoard.OldX.OldY
  271.     AttackerID = GetPiecePos(OldX, OldY)
  272.     if (AttackerID == 0) then do
  273.         EasyRequest Chess_Error "MoveCreatesCheck:_Anonymous_Attacker!" Okay
  274.         return 1
  275.         end
  276.     if (AttackerID < 0) then do
  277.         AttackerID = abs(AttackerID)
  278.         nAttackerSide = 2
  279.         end
  280.     else do
  281.         nAttackerSide = 1
  282.         end
  283.             
  284.     TargetPiece = ChessBoard.X.Y
  285.     TargetID    = 0            /* Default = unset/error */    
  286.     if (TargetPiece ~= Piece.BLANK) then do
  287.     TargetID = GetPiecePos(X,Y)
  288.     if (TargetID == 0) then do
  289.         EasyRequest Chess_Error "MoveCreatesCheck:_Anonymous_defender!" Okay
  290.         return 1
  291.         end
  292.     if (TargetID < 0) then do
  293.         TargetID = abs(TargetID)
  294.         nTargetSide = 2
  295.         end
  296.     else do
  297.         nTargetSide = 1
  298.         end
  299.     PiecePosX.nTargetSide.TargetID = 9999
  300.     PiecePosY.nTargetSide.TargetID = 9999
  301.     end
  302.  
  303.     /* Move the attacker, on both arrays */
  304.         PiecePosX.nAttackerSide.AttackerID = X
  305.         PiecePosY.nAttackerSide.AttackerID = Y
  306.     ChessBoard.X.Y = AttackerPiece              /* Then put the piece in the new spot! */
  307.  
  308.     /* Erase the attacker from his old position */
  309.     ChessBoard.OldX.OldY = Piece.BLANK
  310.  
  311.     /* Now see if we have a check situation */
  312.     ReturnFlag = IsInCheck(CheckX,CheckY)
  313.     
  314.     /* Clean up from our little sim -- move piece back and replace victim */
  315.     ChessBoard.OldX.OldY = AttackerPiece
  316.     PiecePosX.nAttackerSide.AttackerID = OldX
  317.     PiecePosY.nAttackerSide.AttackerID = OldY
  318.     
  319.     ChessBoard.X.Y = TargetPiece
  320.     if (TargetID ~= 0) then do
  321.         PiecePosX.nTargetSide.TargetID = X
  322.         PiecePosY.nTargetSide.TargetID = Y
  323.         end
  324.     
  325.     return ReturnFlag
  326.     
  327.  
  328.     
  329. /* --------------------------------------------------------------- */
  330. /* procedure UpdatePiecePos                               */
  331. /* --------------------------------------------------------------- */
  332. UpdatePiecePos: procedure expose ChessBoard. PiecePosX. PiecePosY.
  333.     parse arg OldX, OldY, X, Y
  334.     
  335.     ThisPiece = GetPiecePos(OldX, OldY)
  336.     
  337.     if (ThisPiece == 0) then do
  338.         EasyRequest Chess_Error "UpdatePiecePos:update_empty_square?_huh?" Okay
  339.         return 0
  340.         end
  341.         
  342.     if (ThisPiece > 0) then do
  343.         PiecePosX.1.ThisPiece = X
  344.         PiecePosY.1.ThisPiece = Y
  345.         return 1
  346.         end
  347.     else do
  348.         ThisPiece = abs(ThisPiece)
  349.         PiecePosX.2.ThisPiece = X
  350.         PiecePosY.2.ThisPiece = Y
  351.         return 1
  352.         end
  353.     
  354.     EasyRequest Chess_Error "UpdatePiecePos_error-not_found" Okay
  355.     return 0
  356.  
  357.  
  358.  
  359.  
  360. /* --------------------------------------------------------------- */
  361. /* procedure GetPiecePos                              */
  362. /*                                   */
  363. /* Given a set of co-ordinates, this function returns the PiecePos */
  364. /* index/ID of the piece there.  Positive values is for Side1 (top */
  365. /* and negative values are for side2 (bottom).  0 = blank/error.   */
  366. /* --------------------------------------------------------------- */
  367. GetPiecePos: procedure expose PiecePosX. PiecePosY. ChessBoard.
  368.     parse arg X, Y
  369.     
  370.     if ((ChessBoard.X.Y == 0)|(X < 0)|(X > 7)|(Y < 0)|(Y > 7)) then return 0
  371.         
  372.     if (ChessBoard.X.Y > 0) then do
  373.         pi = 1
  374.         do while (pi < 17)
  375.             if ((PiecePosX.1.pi == X)&(PiecePosY.1.pi == Y)) then do
  376.                 return pi
  377.                 end
  378.             pi = pi + 1
  379.             end
  380.         end
  381.     else do
  382.         pi = 1
  383.         do while (pi < 17)
  384.             if ((PiecePosX.2.pi == X)&(PiecePosY.2.pi == Y)) then do
  385.                 return -pi
  386.                 end
  387.             pi = pi + 1
  388.             end
  389.         end
  390.     return 0
  391.  
  392.  
  393.  
  394. /* --------------------------------------------------------------- */
  395. /* procedure CheckMove                          */
  396. /* --------------------------------------------------------------- */
  397. CheckMove: procedure expose ChessBoard. piece. PiecePosX. PiecePosY.
  398.     parse arg XFrom, YFrom, XTo, YTo, BCheckForCheck
  399.     
  400.     /* A move off of the board is illegal */
  401.     if ((XTo < 0)|(XTo > 7)|(YTo < 0)|(YTo > 7)) then return 0
  402.  
  403.     /* A move from off of the board is illegal */
  404.     if ((XFrom < 0)|(XFrom > 7)|(YFrom < 0)|(YFrom > 7)) then return 0
  405.     
  406.     /* Blanks can't move */
  407.     if (ChessBoard.XFrom.YFrom == Piece.BLANK) then return 0
  408.     
  409.     /* A move to the same spot we're on is illegal */
  410.     if ((XFrom == XTo)&(YFrom == YTo)) then return 0
  411.         
  412.     /* A move onto one of your own pieces is illegal */
  413.     if ((ChessBoard.XTo.YTo * ChessBoard.XFrom.YFrom) > 0) then return 0
  414.  
  415.     /* Rules for the PAWN */    
  416.     if (abs(ChessBoard.XFrom.YFrom) == Piece.PAWN) then do
  417.     
  418.         if (ChessBoard.XFrom.YFrom < 0) then do
  419.             PawnMoveDir = -1 
  420.             end
  421.             else PawnMoveDir = 1
  422.         if ((XTo == XFrom)&(ChessBoard.XTo.YTo ~= Piece.BLANK)) then return 0
  423.         if ((XTo == XFrom)&(abs(YFrom - YTo) == 2)) then do
  424.             /* First move for a pawn can be two spaces, if both spaces are blank */
  425.             Ytemp = YFrom+PawnMoveDir
  426.             if ((ChessBoard.XFrom.Ytemp) ~= Piece.BLANK) then return 0
  427.             if ((YFrom == 1)&(PawnMoveDir ~= 1)) then return 0
  428.             if ((YFrom == 6)&(PawnMoveDir ~= -1)) then return 0
  429.             if ((YFrom ~= 1)&(YFrom ~= 6)) then return 0
  430.             end
  431.         else do
  432.             if (YTo ~= (YFrom + PawnMoveDir)) then return 0
  433.             if (abs(XFrom - XTo) > 1) then return 0
  434.             if ((abs(XFrom - XTo) == 1)&(ChessBoard.XTo.YTo == Piece.BLANK)) then return 0    
  435.             end
  436.         end 
  437.     
  438.     /* Rules for the ROOK */
  439.     if (abs(ChessBoard.XFrom.YFrom) == Piece.ROOK) then do
  440.         if ((XFrom ~= XTo)&(YFrom ~= YTo)) then return 0
  441.         if (GlideOK(XFrom,YFrom,XTo,YTo) == 0) then return 0
  442.         end
  443.         
  444.     /* Rules for the KNIGHT */
  445.     if (abs(ChessBoard.XFrom.YFrom) == Piece.KNIGHT) then do
  446.         if (((abs(XFrom - XTo) ~= 2)|(abs(YFrom - YTo) ~= 1))&((abs(XFrom - XTo) ~= 1)|(abs(YFrom - YTo) ~= 2))) then return 0
  447.         end
  448.         
  449.     /* Rules for the BISHOP */
  450.     if (abs(ChessBoard.XFrom.YFrom) == Piece.BISHOP) then do
  451.         if (abs(XFrom - XTo) ~= abs(YFrom - YTo)) then return 0
  452.         if (GlideOK(XFrom,YFrom,XTo,YTo) == 0) then return 0
  453.         end
  454.  
  455.     /* Rules for the QUEEN */
  456.     if (abs(ChessBoard.XFrom.YFrom) == Piece.QUEEN) then do
  457.         if ((abs(XFrom - XTo) ~= abs(YFrom - YTo))&((XFrom ~= XTo)&(YFrom ~= YTo))) then return 0
  458.         if (GlideOK(XFrom,YFrom,XTo,YTo) == 0) then return 0
  459.         end
  460.  
  461.     /* Rules for the KING */
  462.     if (abs(ChessBoard.XFrom.YFrom) == Piece.KING) then do
  463.         if ((abs(XTo - XFrom) > 1)|(abs(YTo - YFrom) > 1)) then return 0
  464.         end
  465.     
  466.     if (BCheckForCheck == 0) then return 1
  467.     
  468.     /* Get king's co-ordinates */
  469.     if (Chessboard.XFrom.YFrom > 0) then do
  470.         KingPosX = PiecePosX.1.1
  471.         KingPosY = PiecePosY.1.1        
  472.         end
  473.     else do
  474.         KingPosX = PiecePosX.2.1
  475.         KingPosY = PiecePosY.2.1
  476.         end
  477.  
  478.     /* If king is moving, check were he WILL be, not where he IS */
  479.     if (abs(ChessBoard.XFrom.YFrom) == Piece.KING) then do
  480.         KingPosX = XTo
  481.         KingPosY = YTo
  482.         end
  483.         
  484.     if (MoveCreatesCheck(XFrom, YFrom, XTo, YTo, KingPosX, KingPosY) == 1) then return 0
  485.             
  486.     /* If we passed all these tests, we're ok */        
  487.     return 1
  488.     
  489.     
  490.     
  491. /* --------------------------------------------------------------- */
  492. /* procedure GlideOK                              */
  493. /* --------------------------------------------------------------- */
  494. GlideOK:    procedure expose ChessBoard. piece.
  495.     parse arg XFrom, YFrom, XTo, YTo
  496.     
  497.     xd = 0
  498.     yd = 0
  499.         
  500.     if ((XTo - XFrom) > 0) then xd = 1
  501.     if ((XTo - XFrom) < 0) then xd = -1
  502.     if ((YTo - YFrom) > 0) then yd = 1
  503.     if ((YTo - YFrom) < 0) then yd = -1
  504.  
  505.     x = XFrom + xd    /* Start scanning after where piece already is */
  506.     y = YFrom + yd
  507.     
  508.     xgoal = XTo 
  509.     ygoal = YTo 
  510.     
  511.     do while ((x ~= xgoal)|(y ~= ygoal))
  512.         if (ChessBoard.x.y ~= Piece.BLANK) then return 0
  513.         if ((x<0)|(y<0)|(x>7)|(y>7)) then do
  514.             EasyRequest Chess_Error "Glide_error!" Okay
  515.             return 0
  516.             end
  517.         x = x + xd
  518.         y = y + yd
  519.         end
  520.         
  521.     return 1
  522.     
  523.  
  524. /* --------------------------------------------------------------- */
  525. /* procedure                                */
  526. /*                                    */
  527. /* Returns 1 if the given square is in danger, otherwise 0         */
  528. /* --------------------------------------------------------------- */
  529. IsInCheck: procedure expose ChessBoard. PiecePosX. PiecePosY. piece.
  530.     parse arg X, Y
  531.         
  532.     
  533.     if (ChessBoard.X.Y == 0) then do
  534.         EasyRequest Chess_Error "IsInCheck_:_Square_is_empty!" Okay
  535.         return 0
  536.         end
  537.         
  538.     if (ChessBoard.X.Y > 0) then SideToCheck = 2
  539.     if (ChessBoard.X.Y < 0) then SideToCheck = 1
  540.     
  541.     pi = 1
  542.     do while (pi < 17)
  543.         if (CheckMove(PiecePosX.SideToCheck.pi,PiecePosY.SideToCheck.pi,X,Y,0) == 1) then return 1
  544.         pi = pi + 1
  545.     end
  546.     return 0
  547.  
  548.  
  549.  
  550. /* --------------------------------------------------------------- */
  551. /* procedure                                */
  552. /* --------------------------------------------------------------- */
  553. InitChessArray: procedure expose ChessBoard. piece. PiecePosX. PiecePosY.
  554.  
  555.    /* Set Kings */
  556.    ChessBoard.3.0 = Piece.KING
  557.    ChessBoard.3.7 = -Piece.KING
  558.  
  559.    /* Set king position markers */
  560.    PiecePosX.1.1 = 3
  561.    PiecePosY.1.1 = 0
  562.    PiecePosX.2.1 = 3
  563.    PiecePosY.2.1 = 7
  564.  
  565.    /* Set Queens */
  566.    ChessBoard.4.0 = Piece.QUEEN
  567.    ChessBoard.4.7 = -Piece.QUEEN
  568.  
  569.    /* Set queen position markers */
  570.    PiecePosX.1.2 = 4
  571.    PiecePosY.1.2 = 0
  572.    PiecePosX.2.2 = 4
  573.    PiecePosY.2.2 = 7
  574.  
  575.    /* Set rooks */
  576.    ChessBoard.0.0 = Piece.ROOK
  577.    ChessBoard.7.0 = Piece.ROOK
  578.    ChessBoard.0.7 = -Piece.ROOK
  579.    ChessBoard.7.7 = -Piece.ROOK
  580.  
  581.    /* Set rook position markers */
  582.    PiecePosX.1.3 = 0
  583.    PiecePosY.1.3 = 0
  584.    PiecePosX.1.4 = 7
  585.    PiecePosY.1.4 = 0
  586.    
  587.    PiecePosX.2.3 = 0
  588.    PiecePosY.2.3 = 7
  589.    PiecePosX.2.4 = 7
  590.    PiecePosY.2.4 = 7
  591.    
  592.    /* Set knights */
  593.    ChessBoard.1.0 = Piece.KNIGHT
  594.    ChessBoard.6.0 = Piece.KNIGHT
  595.    ChessBoard.1.7 = -Piece.KNIGHT
  596.    ChessBoard.6.7 = -Piece.KNIGHT
  597.  
  598.    /* Set knight position markers */
  599.    PiecePosX.1.5 = 1
  600.    PiecePosY.1.5 = 0
  601.    PiecePosX.1.6 = 6
  602.    PiecePosY.1.6 = 0
  603.    
  604.    PiecePosX.2.5 = 1
  605.    PiecePosY.2.5 = 7
  606.    PiecePosX.2.6 = 6
  607.    PiecePosY.2.6 = 7
  608.  
  609.    /* Set bishops */
  610.    ChessBoard.2.0 = Piece.BISHOP
  611.    ChessBoard.5.0 = Piece.BISHOP
  612.    ChessBoard.2.7 = -Piece.BISHOP
  613.    ChessBoard.5.7 = -Piece.BISHOP
  614.  
  615.    /* Set bishop position markers */
  616.    PiecePosX.1.7 = 2
  617.    PiecePosY.1.7 = 0
  618.    PiecePosX.1.8 = 5
  619.    PiecePosY.1.8 = 0
  620.    
  621.    PiecePosX.2.7 = 2
  622.    PiecePosY.2.7 = 7
  623.    PiecePosX.2.8 = 5
  624.    PiecePosY.2.8 = 7   
  625.  
  626.    /* Set rows of pawns */
  627.    jx = 0
  628.    do while (jx < 8)
  629.        ChessBoard.jx.1 = Piece.PAWN
  630.        ppTemp = jx + 9
  631.        PiecePosX.1.ppTemp = jx
  632.        PiecePosY.1.ppTemp = 1
  633.     jx = jx + 1
  634.        end
  635.    
  636.    jx = 0
  637.    do while (jx < 8)
  638.     ChessBoard.jx.6 = -1        /* - means bottom team */
  639.        ppTemp = jx + 9
  640.        PiecePosX.2.ppTemp = jx
  641.        PiecePosY.2.ppTemp = 6
  642.     jx = jx + 1
  643.     end
  644.   
  645.    /* Center of board is all blanks */
  646.    jy = 2
  647.    do while (jy < 6)
  648.     jx = 0
  649.     do while (jx < 8)
  650.         ChessBoard.jx.jy = Piece.BLANK
  651.         jx = jx + 1
  652.     end
  653.     jy = jy + 1
  654.    end
  655.  
  656.    return 1
  657.  
  658.  
  659.  
  660. /* --------------------------------------------------------------- */
  661. /* procedure DrawChessBoard                       */
  662. /* --------------------------------------------------------------- */
  663. DrawChessBoard: procedure expose ChessBoard. BoardWidth BoardHeight ToolBarHeight SQUAREPEN1 SQUAREPEN2 SIDE1PEN SIDE2PEN piece. BFlood
  664.  
  665.    /* Say what we're doing */
  666.    SetWindowTitle '"'||"Drawing Chess Board, Please Wait"||'"'
  667.    SetRemoteWindowTitle '"'||"Drawing Chess Board, Please Wait"||'"'
  668.  
  669.    /* Examine window to get dimensions */
  670.    GetWindowAttrs stem winattrs.
  671.    BoardWidth = winattrs.width  - 58
  672.    BoardHeight= winattrs.height - 53 - ToolBarHeight
  673.  
  674.    /* Clear Screen */
  675.    clear
  676.    jy = 0
  677.    do while (jy < 8)
  678.     jx = 0
  679.     do while (jx < 8)
  680.         success = DrawPiece(jx, jy, ChessBoard.jx.jy, BFlood)
  681.         jx = jx + 1
  682.     end
  683.     jy = jy + 1
  684.    end
  685.  
  686.    return 1
  687.     
  688. /* --------------------------------------------------------------- */
  689. /* procedure SquareColor                                              */
  690. /*                                                                      */
  691. /* Given the X,Y co-ordinates (0-7,0-7) of a chess square, return  */
  692. /* its pen color.                                                    */
  693. /* --------------------------------------------------------------- */
  694. SquareColor: procedure expose SQUAREPEN1 SQUAREPEN2
  695.     parse arg XX, YY
  696.  
  697. if ((XX+ YY)/2) = trunc((XX + YY)/2) then
  698.     return SQUAREPEN1
  699. else
  700.     return SQUAREPEN2 
  701.  
  702.  
  703. /* --------------------------------------------------------------- */
  704. /* procedure SelectChessSquare                       */
  705. /* --------------------------------------------------------------- */
  706. SelectChessSquare: procedure expose BoardWidth BoardHeight ToolBarHeight
  707.     parse arg ChessSquareSelectX, ChessSquareSelectY, PenToSelectWith
  708.  
  709.    xleft   = trunc(BoardWidth / 8) * ChessSquareSelectX
  710.    ytop    = (trunc(BoardHeight / 8) * ChessSquareSelectY) + ToolBarHeight
  711.    xright  = xleft + trunc(BoardWidth / 8)
  712.    ybottom = ytop + trunc(BoardHeight / 8)
  713.  
  714.    setfpen PenToSelectWith
  715.    square xleft ytop (xright-1) (ybottom-1)
  716.    return 1
  717.  
  718.  
  719. /* --------------------------------------------------------------- */
  720. /* procedure ParseMove                           */
  721. /* --------------------------------------------------------------- */
  722. ParseMove: procedure expose ChessBoard. piece. PiecePosX. PiecePosY.
  723.     parse arg MoveString
  724.     
  725.    /* parses a move of the form @ABCD@ , where 
  726.        A = X1, B = Y1, C = X2, D = Y2.  No checking need be done
  727.        on the move, as that will all have been done before allowing
  728.        it to be sent */
  729.        
  730.    leftpart = left(MoveString,3)
  731.    rightpart = right(MoveString,3)
  732.  
  733. /*   if ((left(leftpart,1) ~= '@')|(right(rightpart,1) ~= '@')) then return 0 */
  734.  
  735.    leftpart = right(leftpart,2)
  736.    rightpart = left(rightpart,2)
  737.    
  738.    mx1 = left(leftpart,1)
  739.    my1 = right(leftpart,1)
  740.    mx2 = left(rightpart,1)
  741.    my2 = right(rightpart,1)
  742.    
  743.    if (UpdatePiecePos(mx1, my1, mx2, my2) == 0) then do
  744.        EasyRequeset Chess_Error "555:_UPP_failed" Okay
  745.        return 0
  746.        end    
  747.  
  748.    /* Was there a death here?  If so, remove dying piece */
  749.    if (ChessBoard.mx2.my2 ~= Piece.BLANK) then do
  750.        VictimPiece = GetPiecePos(mx2, my2)
  751.     if (VictimPiece > 0) then do
  752.         PiecePosX.1.VictimPiece = 9999
  753.         PiecePosY.1.VictimPiece = 9999
  754.         end
  755.     else do
  756.         VictimPiece = abs(VictimPiece)
  757.         PiecePosX.2.VictimPiece = 9999
  758.         PiecePosY.2.VictimPiece = 9999
  759.         end
  760.     end
  761.     
  762.    ChessBoard.mx2.my2 = ChessBoard.mx1.my1  /* Then put the piece in the new spot! */
  763.    ChessBoard.mx1.my1 = Piece.BLANK
  764.    
  765.    return 1
  766.    
  767.  
  768.  
  769.  
  770. /* --------------------------------------------------------------- */
  771. /* procedure UpdateStatus                                             */
  772. /* --------------------------------------------------------------- */
  773. UpdateStatus: procedure expose turn BConnectMode BActive ACTIVE PASSIVE
  774.     
  775.     /* Say whose turn it is */
  776.     if (turn ~= BActive) then LocalOrRemote = "It's Their Turn" 
  777.     if ((BConnectMode == 0)|(turn == BActive)) then LocalOrRemote = "It's Your Turn"
  778.  
  779.     if (turn == ACTIVE) then do
  780.         LocalOrRemote = '"' || LocalOrRemote || " (White)" || '"'
  781.         end
  782.         else do
  783.         LocalOrRemote = '"' || LocalOrRemote || " (Black)" || '"'
  784.         end
  785.             
  786.     SetWindowTitle LocalOrRemote
  787.     return 1
  788.     
  789.  
  790.  
  791. /* --------------------------------------------------------------- */
  792. /* procedure DrawPiece                                              */
  793. /* --------------------------------------------------------------- */
  794. DrawPiece: procedure expose BoardWidth BoardHeight ToolBarHeight SQUAREPEN1 SQUAREPEN2 SIDE1PEN SIDE2PEN piece.
  795.     parse arg X, Y, PieceCode, BFlood
  796.     
  797.     /* Decode PieceCode */
  798.     PieceColor = SIDE1PEN
  799.     
  800.     if (PieceCode < 0) then do
  801.         PieceCode = abs(PieceCode)
  802.         PieceColor = SIDE2PEN
  803.         end
  804.     
  805.     /* Get co-ords of our square */
  806.     xleft   = trunc(BoardWidth / 8) * X
  807.     ytop    = (trunc(BoardHeight / 8) * Y) + ToolBarHeight
  808.     xd      = trunc(BoardWidth / 8) - 1
  809.     yd      = trunc(BoardHeight/ 8) - 1
  810.     xright  = xleft + xd
  811.     ybottom = ytop + yd
  812.     xcenter = (xleft + trunc(xd/2)) 
  813.     ycenter = (ytop + trunc(yd/2)) 
  814.     
  815.     /* First thing we need to do is erase the square */
  816.     sqc = SquareColor(X, Y)
  817.     setfpen sqc
  818.     square xleft ytop xright ybottom fill
  819.  
  820.     /* If we're doing a filled mode draw, then outline in the other team's color */
  821.     if (BFlood > 0) then do
  822.         if (PieceColor == SIDE1PEN) then do
  823.             OutlineColor = SIDE2PEN
  824.             end 
  825.         else do
  826.             OutlineColor = SIDE1PEN
  827.             end
  828.         end
  829.         else do
  830.             OutlineColor = PieceColor
  831.         end             
  832.  
  833.     /* Set color to appropriate side */
  834.     setfpen OutlineColor
  835.         
  836.     if (PieceCode == piece.PAWN) then do
  837.         penreset
  838.         pen (xleft+trunc(xd*.56))  (ytop+trunc(yd*.47))
  839.         pen (xleft+trunc(xd*.6))   (ytop+trunc(yd*.8))
  840.         pen (xleft+trunc(xd*.65))  (ytop+trunc(yd*.9))
  841.         pen (xleft+trunc(xd*.35))  (ytop+trunc(yd*.9))
  842.         pen (xleft+trunc(xd*.4))   (ytop+trunc(yd*.8))
  843.         pen (xleft+trunc(xd*.44))  (ytop+trunc(yd*.47))
  844.         if BFlood > 0 then do
  845.             setfpen PieceColor
  846.             circle (xleft+trunc(xd*.5)) (ytop+trunc(yd*.38)) (trunc(xd*.16)) (trunc(yd*.16)) fill
  847.             setfpen OutlineColor
  848.             end
  849.         circle (xleft+trunc(xd*.5)) (ytop+trunc(yd*.38)) (trunc(xd*.16)) (trunc(yd*.16))
  850.         if BFlood > 0 then do
  851.             setfpen PieceColor
  852.             flood xcenter (ytop + trunc(yd * .8))
  853.             end
  854.         end
  855.         else 
  856.     if (PieceCode == piece.ROOK) then do
  857.         penreset
  858.         pen (xleft+trunc(xd*.3))   (ytop+trunc(yd*.2))
  859.         pen (xleft+trunc(xd*.4))   (ytop+trunc(yd*.2))
  860.         pen (xleft+trunc(xd*.4))   (ytop+trunc(yd*.3))
  861.         pen (xleft+trunc(xd*.45))  (ytop+trunc(yd*.3))
  862.         pen (xleft+trunc(xd*.45))  (ytop+trunc(yd*.2))
  863.         pen (xleft+trunc(xd*.55))  (ytop+trunc(yd*.2))
  864.         pen (xleft+trunc(xd*.55))  (ytop+trunc(yd*.3))
  865.         pen (xleft+trunc(xd*.6))   (ytop+trunc(yd*.3))
  866.         pen (xleft+trunc(xd*.6))   (ytop+trunc(yd*.2))
  867.         pen (xleft+trunc(xd*.7))   (ytop+trunc(yd*.2))
  868.         pen (xleft+trunc(xd*.7))   (ytop+trunc(yd*.3))
  869.         pen (xleft+trunc(xd*.6))   (ytop+trunc(yd*.4))
  870.         pen (xleft+trunc(xd*.6))   (ytop+trunc(yd*.7))
  871.         pen (xleft+trunc(xd*.75))  (ytop+trunc(yd*.9))
  872.         pen (xleft+trunc(xd*.25))  (ytop+trunc(yd*.9))
  873.         pen (xleft+trunc(xd*.4))   (ytop+trunc(yd*.7))
  874.         pen (xleft+trunc(xd*.4))   (ytop+trunc(yd*.4))
  875.         pen (xleft+trunc(xd*.3))   (ytop+trunc(yd*.3))
  876.         pen (xleft+trunc(xd*.3))   (ytop+trunc(yd*.2))
  877.         setfpen PieceColor
  878.         if BFlood > 0 then flood (xleft+trunc(xd*.5)) (ytop + trunc(yd*.5))
  879.         end
  880.         else
  881.     if (PieceCode == piece.KNIGHT) then do
  882.         penreset 
  883.         pen (xleft+trunc(xd*.3))  (ytop+trunc(yd*.2))
  884.         pen (xleft+trunc(xd*.3))  (ytop+trunc(yd*.10))
  885.         pen (xleft+trunc(xd*.33)) (ytop+trunc(yd*.19))
  886.         pen (xleft+trunc(xd*.6))  (ytop+trunc(yd*.2))
  887.         pen (xleft+trunc(xd*.7))  (ytop+trunc(yd*.4))
  888.         pen (xleft+trunc(xd*.65)) (ytop+trunc(yd*.45))
  889.         pen (xleft+trunc(xd*.5))  (ytop+trunc(yd*.4))
  890.         pen (xleft+trunc(xd*.5))  (ytop+trunc(yd*.5))
  891.         pen (xleft+trunc(xd*.6))  (ytop+trunc(yd*.6))
  892.         pen (xleft+trunc(xd*.75)) (ytop+trunc(yd*.9))
  893.         pen (xleft+trunc(xd*.25)) (ytop+trunc(yd*.9))
  894.         pen (xleft+trunc(xd*.3))  (ytop+trunc(yd*.8))
  895.         pen (xleft+trunc(xd*.3))  (ytop+trunc(yd*.7))
  896.         pen (xleft+trunc(xd*.2))  (ytop+trunc(yd*.4))
  897.         pen (xleft+trunc(xd*.3))  (ytop+trunc(yd*.2))
  898.         setfpen PieceColor
  899.         if BFlood > 0 then flood (xleft+trunc(xd*.5)) (ytop+trunc(yd*.75))
  900.         setfpen OutlineColor
  901.         circle (xleft+trunc(xd*.55)) (ytop+trunc(yd*.3)) trunc(xd/20) trunc(yd/20) fill
  902.         end
  903.         else
  904.     if (PieceCode == piece.BISHOP) then do
  905.         penreset
  906.         pen (xleft+trunc(xd*.48))  (ytop+trunc(yd*.2))
  907.         pen (xleft+trunc(xd*.4))   (ytop+trunc(yd*.3))
  908.         pen (xleft+trunc(xd*.45))  (ytop+trunc(yd*.4))
  909.         pen (xleft+trunc(xd*.35))  (ytop+trunc(yd*.7))
  910.         pen (xleft+trunc(xd*.35))  (ytop+trunc(yd*.9))
  911.         pen (xleft+trunc(xd*.65))  (ytop+trunc(yd*.9))
  912.         pen (xleft+trunc(xd*.65))  (ytop+trunc(yd*.7))
  913.         pen (xleft+trunc(xd*.55))  (ytop+trunc(yd*.4))
  914.         pen (xleft+trunc(xd*.6))   (ytop+trunc(yd*.3))
  915.         pen (xleft+trunc(xd*.52))  (ytop+trunc(yd*.2))
  916.         if BFlood > 0 then do
  917.             setfpen PieceColor
  918.             circle (xleft+trunc(xd*.5)) (ytop+trunc(yd*.2)) trunc(xd*.08) trunc(yd*.08) fill
  919.             setfpen OutlineColor
  920.             end
  921.         circle (xleft+trunc(xd*.5)) (ytop+trunc(yd*.2)) trunc(xd*.08) trunc(yd*.08)
  922.         if BFlood > 0 then do
  923.             setfpen PieceColor
  924.                flood (xleft+trunc(xd*.5)) (ytop+trunc(yd*.8))
  925.             end
  926.         end
  927.         else
  928.     if (PieceCode == piece.QUEEN) then do
  929.         penreset
  930.         pen (xleft+trunc(xd*.4)) (ytop+trunc(yd*.1))
  931.         pen (xleft+trunc(xd*.6)) (ytop+trunc(yd*.1))
  932.         pen (xleft+trunc(xd*.7)) (ytop+trunc(yd*.15))
  933.         pen (xleft+trunc(xd*.6)) (ytop+trunc(yd*.3))
  934.         pen (xleft+trunc(xd*.6)) (ytop+trunc(yd*.7))
  935.         pen (xleft+trunc(xd*.8)) (ytop+trunc(yd*.9))
  936.         pen (xleft+trunc(xd*.2)) (ytop+trunc(yd*.9))
  937.         pen (xleft+trunc(xd*.4)) (ytop+trunc(yd*.7))
  938.         pen (xleft+trunc(xd*.4)) (ytop+trunc(yd*.3))
  939.         pen (xleft+trunc(xd*.3)) (ytop+trunc(yd*.15))
  940.         pen (xleft+trunc(xd*.4)) (ytop+trunc(yd*.1))
  941.         setfpen PieceColor
  942.         if BFlood > 0 then flood (xleft+trunc(xd*.5)) (ytop + trunc(yd*.75))
  943.         end
  944.         else
  945.     if (PieceCode == piece.KING) then do
  946.         penreset
  947.         pen (xleft+trunc(xd*.47)) (ytop+trunc(yd*.1))
  948.         pen (xleft+trunc(xd*.53)) (ytop+trunc(yd*.1))
  949.         pen (xleft+trunc(xd*.53)) (ytop+trunc(yd*.2))
  950.         pen (xleft+trunc(xd*.57)) (ytop+trunc(yd*.2))
  951.         pen (xleft+trunc(xd*.57)) (ytop+trunc(yd*.3))
  952.         pen (xleft+trunc(xd*.53)) (ytop+trunc(yd*.3))
  953.         pen (xleft+trunc(xd*.53)) (ytop+trunc(yd*.4))
  954.         pen (xleft+trunc(xd*.6))  (ytop+trunc(yd*.5))
  955.         pen (xleft+trunc(xd*.55)) (ytop+trunc(yd*.6))
  956.         pen (xleft+trunc(xd*.6))  (ytop+trunc(yd*.8))
  957.         pen (xleft+trunc(xd*.7))  (ytop+trunc(yd*.9))
  958.         pen (xleft+trunc(xd*.3))  (ytop+trunc(yd*.9))
  959.         pen (xleft+trunc(xd*.4))  (ytop+trunc(yd*.8))
  960.         pen (xleft+trunc(xd*.45)) (ytop+trunc(yd*.6))
  961.         pen (xleft+trunc(xd*.4))  (ytop+trunc(yd*.5))
  962.         pen (xleft+trunc(xd*.47)) (ytop+trunc(yd*.4))
  963.         pen (xleft+trunc(xd*.47)) (ytop+trunc(yd*.3))
  964.         pen (xleft+trunc(xd*.43)) (ytop+trunc(yd*.3))
  965.         pen (xleft+trunc(xd*.43)) (ytop+trunc(yd*.2))
  966.         pen (xleft+trunc(xd*.47)) (ytop+trunc(yd*.2))
  967.         pen (xleft+trunc(xd*.47)) (ytop+trunc(yd*.1))
  968.             setfpen PieceColor
  969.         if BFlood > 0 then flood (xleft+trunc(xd*.5)) (ytop+trunc(yd*.7))
  970.         end
  971.     return 1